package com.eastfair.imaster.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperCacheServiceImpl;
import com.eastfair.cache.operations.SpeakerListCacheKeyBuilder;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.base.entity.Entity;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.model.CacheKeyBuilder;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.imaster.dao.SpeakerListMapper;
import com.eastfair.imaster.dto.SpeakerListDTO;
import com.eastfair.imaster.dto.SpeakerListPageQuery;
import com.eastfair.imaster.entity.SpeakerList;
import com.eastfair.imaster.service.SpeakerListDetailsService;
import com.eastfair.imaster.service.SpeakerListService;
import com.eastfair.imaster.service.SpeakerService;
import com.eastfair.imaster.vo.SpeakerListVO;
import com.eastfair.projectcore.api.ProjectCoreServiceFeign;
import com.eastfair.core.snowflake.DefaultUidGenerator;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 业务实现类
 * 嘉宾列表
 * </p>
 *
 * @author zjn
 * @date 2021-09-02
 */
@Slf4j
@Service
@DS("#thread.tenant")
public class SpeakerListServiceImpl extends SuperCacheServiceImpl<SpeakerListMapper, SpeakerList> implements SpeakerListService {

    @Autowired
    ProjectCoreServiceFeign projectCoreServiceFeign;
    @Autowired
    private SpeakerListDetailsService speakerListDetailsService;
    @Autowired
    private SpeakerService speakerService;

    @Override
    protected CacheKeyBuilder cacheKeyBuilder() {
        return new SpeakerListCacheKeyBuilder();
    }

    /**************sharding 分库分表操作 *****************/
    @Override
    public boolean updateByIdOfShard(SpeakerList entity) {
        UpdateWrapper<SpeakerList> updateWrapper = new UpdateWrapper<>();
        //可将指定字段更新为null
        updateWrapper.lambda().eq(SpeakerList::getProjectId, entity.getProjectId()).eq(SpeakerList::getId, entity.getId());
        entity.setProjectId(null);
        //删除缓存
        delCache(entity);
        return SqlHelper.retBool(this.getBaseMapper().update(entity, updateWrapper));
    }

    /**
     * 处理新增相关处理
     *
     * @param model 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerSave(SpeakerList model) {
        //雪花ID
        model.setId(DefaultUidGenerator.getUidOfProjectId(ContextUtil.getProjectId()));
        model.setProjectId(ContextUtil.getProjectId());
        return R.successDef();
    }

    @Override
    public R<Boolean> saveSpeakerList(SpeakerListDTO speakerListDTO) {
        // 新增嘉宾列表实体
        SpeakerList speakerList = BeanUtil.copyProperties(speakerListDTO, SpeakerList.class);
        speakerList.setProjectId(ContextUtil.getProjectId());
        return R.success(save(speakerList));
    }

    @Override
    @GlobalTransactional(name = "deleteById", rollbackFor = Exception.class)
    public R<Boolean> deleteById(Long id) {
        SpeakerList speakerList = SpeakerList.builder()
                .id(id).projectId(ContextUtil.getProjectId()).isDeleted(BusinessConstant.DELETE_YES).build();

        // 删除列表与嘉宾的关系
        speakerListDetailsService.deleteBySpeakerListId(id);

        return R.success(updateByIdOfShard(speakerList));
    }

    @Override
    public R<Boolean> updateById(SpeakerListDTO speakerListDTO) {
        SpeakerList speakerList = BeanUtil.copyProperties(speakerListDTO, SpeakerList.class);
        speakerList.setProjectId(ContextUtil.getProjectId());
        return R.success(updateByIdOfShard(speakerList));
    }

    @Override
    public SpeakerListVO queryById(Long id) {
        QueryWrapper<SpeakerList> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(SpeakerList::getProjectId, ContextUtil.getProjectId()).eq(SpeakerList::getId, id);
        SpeakerList speakerList = getOne(wrapper, false);
        if (speakerList == null) {
            return null;
        }
        return BeanUtil.copyProperties(speakerList, SpeakerListVO.class);
    }

    @Override
    public Page<SpeakerListVO> queryPageList(PageParams<SpeakerListPageQuery> params) {
        QueryWrapper<SpeakerList> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SpeakerList::getProjectId, ContextUtil.getProjectId())
                .eq(SpeakerList::getIsDeleted, BusinessConstant.DELETE_NO)
                .eq(SpeakerList::getIsEnabled, BusinessConstant.ENABLE_YES)
                .orderByDesc(Entity::getUpdateTime);
        return ConvertUtil.convertPage(page(params.buildPage(), queryWrapper), SpeakerListVO.class);
    }

    @Override
    public List<SpeakerListVO> queryList(SpeakerListDTO speakerListDTO) {
        QueryWrapper<SpeakerList> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SpeakerList::getProjectId, ContextUtil.getProjectId())
                .eq(SpeakerList::getIsDeleted, BusinessConstant.DELETE_NO)
                .eq(SpeakerList::getIsEnabled, BusinessConstant.ENABLE_YES)
                .orderByDesc(Entity::getUpdateTime);
        return ConvertUtil.convertList(list(queryWrapper), SpeakerListVO.class);
    }

}
